<template>
	<view @click.stop>
        <view class="d-flex a-center">
            <view class="flex-1 size28 color-222" v-if="title">{{ title }}：</view>
            <up-icon name="plus-circle" color="#999" size="48rpx" stop @click="showAction = true" v-if="fileList.length < count && !readonly"></up-icon>
        </view>
        <view class="row m-top10" v-if="fileList.length">
            <view class="p-re m-right20 m-top20" @click.stop="openFile(item.url)" v-for="(item,index) in fileList" :key="index">
                <image class="img" :src="imgUrls(item.url)" mode="aspectFill" v-if="isImg(item.url)"></image>
                <image class="img" :src="staticImg + matchIcon(item.url)" mode="aspectFit" v-else></image>
                <view class="delBtn flexac p-ab" @click.stop="delFile(index)" v-if="!readonly">
                    <text class="iconfont icon-guanbi2 size24 white"></text>
                </view>
            </view>
        </view>

        <up-action-sheet :show="showAction" :actions="actionList" :round="10" cancelText="取消" closeOnClickOverlay @close="showAction = false" @select="selectType"></up-action-sheet>
	</view>
</template>

<script setup>
	import { ref, onMounted, defineEmits } from 'vue'
    import { useMainStore } from '@/stores/index'
    import { staticImg, domain } from '@/utils/config.js'
    import { imgUrls, showLoading, hideLoading, Toast } from '@/utils/utils.js'

    const mainStore = useMainStore()
    const props = defineProps({
		count: {
			type: Number,
			default: 1
		},
        rawFile: {
			type: String,
			default: ''
		},
        rawList: {
			type: Array,
			default: () => []
		},
        current: {
			type: Number,
			default: 0
		},
        title: {
            type: String,
            default: '附件'
        },
        readonly: {
            type: Boolean,
            default: false
        }
	})

    onMounted(() => {
        if(props.rawFile) fileList.value = props.rawFile.split(',').map(url => ({ url }))
        if(props.rawList.length) fileList.value = props.rawList
    })

    const fileList = ref([])
    const showAction = ref(false)
    const actionList = ref([
        { name: '拍摄', type: 'camera' },
        { name: '从相册选择', type: 'album' },
        { name: '从聊天会话选择文件', type: 'message' }
    ])

    const emit = defineEmits(['getFile'])
    
    const selectType = (item) => {
        let count = props.count - fileList.value.length
        if(item.type == 'camera' || item.type == 'album') {
            uni.chooseImage({
                count,
                sourceType: [item.type],
                success: res => {
                    uploadFiles(res.tempFiles)
                }
            })
        }
        if(item.type == 'message') {
            // #ifdef MP-WEIXIN
            wx.chooseMessageFile({
                count,
                type: 'file', // 支持video、image、file
                success: res => {
                    uploadFiles(res.tempFiles)
                }
            })
            // #endif
        }
    }

    const uploadFiles = (files) => {
        showLoading('正在上传')
        files.forEach((item, index) => {
            uploadFile(item.path, item.name).then(result => {
                fileList.value.push(result)
                if(index == files.length - 1) {
                    hideLoading()
                    emit('getFile', {
                        list: fileList.value, // 多个带name、key
                        file: result.url, // 单个文件只需要路径可用
                        index: props.current
                    })
                }
            })
        })
    }

    const uploadFile = (filePath, name) => {
        return new Promise((resolve, reject) => {
            uni.uploadFile({
                url: domain + '/api/uploadFile',
                filePath,
                name: 'file',
                header: {
                    token: mainStore.token
                },
                success: res => {
                    let result = JSON.parse(res.data)
                    if(result.code != 0) return Toast(result.msg)
                    resolve({
                        url: result.savePath,
                        name: name || result.fileName,
                        key: result.fileKey
                    })
                },
                fail: err => {
                    reject(err)
                }
            })
        })
    }

    const delFile = (index) => {
        fileList.value.splice(index, 1)
        emit('getFile', {
            list: fileList.value,
            file: '',
            index: props.current
        })
    }

    const openFile = (url) => {
        if(isImg(url)) {
            uni.previewImage({
				urls: [imgUrls(url)]
			})
            return 
        }
        showLoading()
		uni.downloadFile({
			url,
			success(res) {
				uni.openDocument({
					filePath: res.tempFilePath,
					complete() {
						hideLoading()
					}
				})
			},
            fail() {
                hideLoading()
            }
		})
    }

    const isImg = (url) => {
		let suffix = url.slice(url.lastIndexOf('.') + 1)
		let all = ['png','jpg','jpeg','gif','webp','bmp']
        return all.includes(suffix.toLowerCase())
	}

    const matchIcon = (url) => {
		let suffix = url.slice(url.lastIndexOf('.') + 1)
		if(suffix == 'txt') {
			return 'text.png'
		} else if(suffix == 'pdf') {
			return 'PDF.png'
		} else if(suffix == 'doc' || suffix == 'docx') {
			return 'word.png'
		} else if(suffix == 'xls' || suffix == 'xlsx') {
			return 'excel.png'
		} else if(suffix == 'ppt' || suffix == 'pptx') {
			return 'slide.png'
		} else {
			return 'unknown.png'
		}
	}
</script>

<style lang="scss" scoped>
	.img {
		width: 100rpx;
		height: 100rpx;
		border-radius: 10rpx;
	}
    .delBtn {
		width: 30rpx;
		height: 30rpx;
		background: rgba(0,0,0,.6);
		border-radius: 50%;
		top: -10rpx;
		right: -10rpx;
	}
</style>
